From 7c659465e2f01209d398d54524a6ad71f6495a09 Mon Sep 17 00:00:00 2001 From: Soeren Sandmann Date: Mon, 20 Oct 2003 18:56:05 +0000 Subject: [PATCH] Add support for OS X like sliding of toolbar items during drag and drop, Mon Oct 20 20:27:22 2003 Soeren Sandmann Add support for OS X like sliding of toolbar items during drag and drop, (#110919, Dave Bordoley) Make dnd highlighting the responsibility of the application. (Fixes #116298, Owen Taylor) * gtk/gtktoolbar.h: Add prototypes for new API. * gtk/gtktoolbar.c (physical_to_logical, logical_to_physical): new functions converting between "position including placeholders" and "position excluding placeholders". (gtk_toolbar_class_init): remove drag_leave and drag_motion handlers (struct _ToolbarContent): new struct containing information related to toolbar items. (gtk_toolbar_highlight_drop_location): new public function (gtk_toolbar_unhighlight_drop_location): new public function * tests/testtoolbar.c (toolbar_drag_motion, toolbar_drag_leave): new functions (main): connect to dnd signals. Make the "New" item expand to make drag and drop more exciting. --- ChangeLog | 26 ++ ChangeLog.pre-2-10 | 26 ++ ChangeLog.pre-2-4 | 26 ++ ChangeLog.pre-2-6 | 26 ++ ChangeLog.pre-2-8 | 26 ++ gtk/gtktoolbar.c | 813 +++++++++++++++++++++++++++++--------------- gtk/gtktoolbar.h | 72 ++-- tests/testtoolbar.c | 34 +- 8 files changed, 748 insertions(+), 301 deletions(-) diff --git a/ChangeLog b/ChangeLog index 79756b31d7..4ec6b36843 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +Mon Oct 20 20:27:22 2003 Soeren Sandmann + + Add support for OS X like sliding of toolbar items during drag and + drop, (#110919, Dave Bordoley) + + Make dnd highlighting the responsibility of the + application. (Fixes #116298, Owen Taylor) + + * gtk/gtktoolbar.h: Add prototypes for new API. + + * gtk/gtktoolbar.c + (physical_to_logical, logical_to_physical): new functions + converting between "position including placeholders" and "position + excluding placeholders". + (gtk_toolbar_class_init): remove drag_leave and drag_motion + handlers + (struct _ToolbarContent): new struct containing information + related to toolbar items. + (gtk_toolbar_highlight_drop_location): new public function + (gtk_toolbar_unhighlight_drop_location): new public function + + * tests/testtoolbar.c + (toolbar_drag_motion, toolbar_drag_leave): new functions + (main): connect to dnd signals. Make the "New" item expand to + make drag and drop more exciting. + Wed Oct 15 22:39:23 2003 Kristian Rietveld * gtk/gtkcomboboxentry.c (gtk_combo_box_entry_init): it's diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 79756b31d7..4ec6b36843 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,29 @@ +Mon Oct 20 20:27:22 2003 Soeren Sandmann + + Add support for OS X like sliding of toolbar items during drag and + drop, (#110919, Dave Bordoley) + + Make dnd highlighting the responsibility of the + application. (Fixes #116298, Owen Taylor) + + * gtk/gtktoolbar.h: Add prototypes for new API. + + * gtk/gtktoolbar.c + (physical_to_logical, logical_to_physical): new functions + converting between "position including placeholders" and "position + excluding placeholders". + (gtk_toolbar_class_init): remove drag_leave and drag_motion + handlers + (struct _ToolbarContent): new struct containing information + related to toolbar items. + (gtk_toolbar_highlight_drop_location): new public function + (gtk_toolbar_unhighlight_drop_location): new public function + + * tests/testtoolbar.c + (toolbar_drag_motion, toolbar_drag_leave): new functions + (main): connect to dnd signals. Make the "New" item expand to + make drag and drop more exciting. + Wed Oct 15 22:39:23 2003 Kristian Rietveld * gtk/gtkcomboboxentry.c (gtk_combo_box_entry_init): it's diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 79756b31d7..4ec6b36843 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,29 @@ +Mon Oct 20 20:27:22 2003 Soeren Sandmann + + Add support for OS X like sliding of toolbar items during drag and + drop, (#110919, Dave Bordoley) + + Make dnd highlighting the responsibility of the + application. (Fixes #116298, Owen Taylor) + + * gtk/gtktoolbar.h: Add prototypes for new API. + + * gtk/gtktoolbar.c + (physical_to_logical, logical_to_physical): new functions + converting between "position including placeholders" and "position + excluding placeholders". + (gtk_toolbar_class_init): remove drag_leave and drag_motion + handlers + (struct _ToolbarContent): new struct containing information + related to toolbar items. + (gtk_toolbar_highlight_drop_location): new public function + (gtk_toolbar_unhighlight_drop_location): new public function + + * tests/testtoolbar.c + (toolbar_drag_motion, toolbar_drag_leave): new functions + (main): connect to dnd signals. Make the "New" item expand to + make drag and drop more exciting. + Wed Oct 15 22:39:23 2003 Kristian Rietveld * gtk/gtkcomboboxentry.c (gtk_combo_box_entry_init): it's diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 79756b31d7..4ec6b36843 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,29 @@ +Mon Oct 20 20:27:22 2003 Soeren Sandmann + + Add support for OS X like sliding of toolbar items during drag and + drop, (#110919, Dave Bordoley) + + Make dnd highlighting the responsibility of the + application. (Fixes #116298, Owen Taylor) + + * gtk/gtktoolbar.h: Add prototypes for new API. + + * gtk/gtktoolbar.c + (physical_to_logical, logical_to_physical): new functions + converting between "position including placeholders" and "position + excluding placeholders". + (gtk_toolbar_class_init): remove drag_leave and drag_motion + handlers + (struct _ToolbarContent): new struct containing information + related to toolbar items. + (gtk_toolbar_highlight_drop_location): new public function + (gtk_toolbar_unhighlight_drop_location): new public function + + * tests/testtoolbar.c + (toolbar_drag_motion, toolbar_drag_leave): new functions + (main): connect to dnd signals. Make the "New" item expand to + make drag and drop more exciting. + Wed Oct 15 22:39:23 2003 Kristian Rietveld * gtk/gtkcomboboxentry.c (gtk_combo_box_entry_init): it's diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 79756b31d7..4ec6b36843 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,29 @@ +Mon Oct 20 20:27:22 2003 Soeren Sandmann + + Add support for OS X like sliding of toolbar items during drag and + drop, (#110919, Dave Bordoley) + + Make dnd highlighting the responsibility of the + application. (Fixes #116298, Owen Taylor) + + * gtk/gtktoolbar.h: Add prototypes for new API. + + * gtk/gtktoolbar.c + (physical_to_logical, logical_to_physical): new functions + converting between "position including placeholders" and "position + excluding placeholders". + (gtk_toolbar_class_init): remove drag_leave and drag_motion + handlers + (struct _ToolbarContent): new struct containing information + related to toolbar items. + (gtk_toolbar_highlight_drop_location): new public function + (gtk_toolbar_unhighlight_drop_location): new public function + + * tests/testtoolbar.c + (toolbar_drag_motion, toolbar_drag_leave): new functions + (main): connect to dnd signals. Make the "New" item expand to + make drag and drop more exciting. + Wed Oct 15 22:39:23 2003 Kristian Rietveld * gtk/gtkcomboboxentry.c (gtk_combo_box_entry_init): it's diff --git a/gtk/gtktoolbar.c b/gtk/gtktoolbar.c index 4eea8f57d6..81860a393c 100644 --- a/gtk/gtktoolbar.c +++ b/gtk/gtktoolbar.c @@ -57,8 +57,8 @@ #define DEFAULT_ICON_SIZE GTK_ICON_SIZE_LARGE_TOOLBAR #define DEFAULT_TOOLBAR_STYLE GTK_TOOLBAR_BOTH -#define MAX_HOMOGENEOUS_N_CHARS 13 /* Items that are wider than this do not participate in - * the homogeneous game. In units of +#define MAX_HOMOGENEOUS_N_CHARS 13 /* Items that are wider than this do not participate + * in the homogeneous game. In units of * pango_font_get_estimated_char_width(). */ @@ -116,14 +116,6 @@ static void gtk_toolbar_screen_changed (GtkWidget *widget, static void gtk_toolbar_map (GtkWidget *widget); static void gtk_toolbar_unmap (GtkWidget *widget); -static void gtk_toolbar_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time_); -static gboolean gtk_toolbar_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time_); static void gtk_toolbar_set_child_property (GtkContainer *container, GtkWidget *child, guint property_id, @@ -183,6 +175,10 @@ static GtkWidget *gtk_toolbar_internal_insert_element (GtkToolbar *tool gpointer user_data, gint position, gboolean use_stock); +static void gtk_toolbar_insert_tool_item (GtkToolbar *toolbar, + GtkToolItem *item, + gint pos, + gboolean is_placeholder); typedef enum { @@ -192,23 +188,38 @@ typedef enum { } ApiMode; #define GTK_TOOLBAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_TOOLBAR, GtkToolbarPrivate)) +typedef struct _ToolbarContent ToolbarContent; +struct _ToolbarContent +{ + GtkToolItem *item; + guint is_overflow : 1; + guint is_placeholder : 1; + gint start_width; + gint goal_width; + gint start_height; + gint goal_height; +}; struct _GtkToolbarPrivate { - GList *items; + GList *content; GtkWidget *arrow; GtkWidget *arrow_button; gboolean show_arrow; - gint drop_index; - GdkWindow *drag_highlight; GtkMenu *menu; GdkWindow *event_window; ApiMode api_mode; GtkSettings *settings; + int idle_id; + GTimer *timer; + gboolean need_sync; + gboolean leaving_dnd; + gboolean in_dnd; + gint n_overflow_items_when_dnd_started; }; static GtkContainerClass *parent_class = NULL; @@ -304,9 +315,6 @@ gtk_toolbar_class_init (GtkToolbarClass *klass) widget_class->unmap = gtk_toolbar_unmap; widget_class->popup_menu = gtk_toolbar_popup_menu; - widget_class->drag_leave = gtk_toolbar_drag_leave; - widget_class->drag_motion = gtk_toolbar_drag_motion; - container_class->add = gtk_toolbar_add; container_class->remove = gtk_toolbar_remove; container_class->forall = gtk_toolbar_forall; @@ -586,12 +594,11 @@ gtk_toolbar_init (GtkToolbar *toolbar) gtk_widget_set_parent (priv->arrow_button, GTK_WIDGET (toolbar)); /* which child position a drop will occur at */ - priv->drop_index = -1; - priv->drag_highlight = NULL; - priv->menu = NULL; priv->show_arrow = TRUE; priv->settings = NULL; + + priv->timer = g_timer_new (); } static gboolean @@ -660,23 +667,6 @@ toolbar_item_is_homogeneous (GtkToolbar *toolbar, return result; } -static void -toolbar_item_set_is_overflow (GtkToolItem *item, - gboolean is_overflow) -{ - g_object_set_data (G_OBJECT (item), "gtk-toolbar-item-is-overflow", GINT_TO_POINTER (is_overflow)); -} - -static gboolean -toolbar_item_get_is_overflow (GtkToolItem *item) -{ - gpointer result; - - result = g_object_get_data (G_OBJECT (item), "gtk-toolbar-item-is-overflow"); - - return GPOINTER_TO_INT (result); -} - static void gtk_toolbar_set_property (GObject *object, guint prop_id, @@ -792,13 +782,6 @@ gtk_toolbar_unrealize (GtkWidget *widget) { GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (widget); - if (priv->drag_highlight) - { - gdk_window_set_user_data (priv->drag_highlight, NULL); - gdk_window_destroy (priv->drag_highlight); - priv->drag_highlight = NULL; - } - if (priv->event_window) { gdk_window_set_user_data (priv->event_window, NULL); @@ -817,7 +800,7 @@ gtk_toolbar_expose (GtkWidget *widget, GtkToolbar *toolbar = GTK_TOOLBAR (widget); GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar); - GList *items; + GList *list; gint border_width; border_width = GTK_CONTAINER (widget)->border_width; @@ -835,16 +818,15 @@ gtk_toolbar_expose (GtkWidget *widget, widget->allocation.height - 2 * border_width); } - items = priv->items; - while (items) + for (list = priv->content; list != NULL; list = list->next) { - GtkToolItem *item = GTK_TOOL_ITEM (items->data); + ToolbarContent *content = list->data; + GtkToolItem *item = content->item; - gtk_container_propagate_expose (GTK_CONTAINER (widget), - GTK_WIDGET (item), - event); - - items = items->next; + if (!content->is_placeholder) + gtk_container_propagate_expose (GTK_CONTAINER (widget), + GTK_WIDGET (item), + event); } gtk_container_propagate_expose (GTK_CONTAINER (widget), @@ -876,10 +858,11 @@ gtk_toolbar_size_request (GtkWidget *widget, max_homogeneous_child_height = 0; max_child_width = 0; max_child_height = 0; - for (list = priv->items; list != NULL; list = list->next) + for (list = priv->content; list != NULL; list = list->next) { GtkRequisition requisition; - GtkToolItem *item = list->data; + ToolbarContent *content = list->data; + GtkToolItem *item = content->item; if (!toolbar_item_visible (toolbar, item)) continue; @@ -903,9 +886,10 @@ gtk_toolbar_size_request (GtkWidget *widget, pack_end_size = 0; pack_front_size = 0; - for (list = priv->items; list != NULL; list = list->next) + for (list = priv->content; list != NULL; list = list->next) { - GtkToolItem *item = list->data; + ToolbarContent *content = list->data; + GtkToolItem *item = content->item; guint size; if (!toolbar_item_visible (toolbar, item)) @@ -1046,8 +1030,9 @@ gtk_toolbar_size_allocate (GtkWidget *widget, gint available_size; gint n_items; gint needed_size; - GList *items; + GList *content; GtkRequisition arrow_requisition; + gint n_overflowed; widget->allocation = *allocation; @@ -1092,13 +1077,14 @@ gtk_toolbar_size_allocate (GtkWidget *widget, } } - n_items = g_list_length (priv->items); + n_items = g_list_length (priv->content); allocations = g_new0 (GtkAllocation, n_items); needed_size = 0; - for (list = priv->items; list != NULL; list = list->next) + for (list = priv->content; list != NULL; list = list->next) { - GtkToolItem *item = list->data; + ToolbarContent *content = list->data; + GtkToolItem *item = content->item; if (toolbar_item_visible (toolbar, item)) needed_size += get_item_size (toolbar, GTK_WIDGET (item)); @@ -1111,12 +1097,15 @@ gtk_toolbar_size_allocate (GtkWidget *widget, else size = available_size; - items = g_list_copy (priv->items); + content = g_list_copy (priv->content); + n_overflowed = 0; + /* calculate widths of pack end items */ - for (list = g_list_last (items), i = 0; list != NULL; list = list->prev, ++i) + for (list = g_list_last (content), i = 0; list != NULL; list = list->prev, ++i) { - GtkToolItem *item = list->data; + ToolbarContent *content = list->data; + GtkToolItem *item = content->item; GtkAllocation *allocation = &(allocations[n_items - i - 1]); gint item_size; @@ -1129,16 +1118,17 @@ gtk_toolbar_size_allocate (GtkWidget *widget, { size -= item_size; allocation->width = item_size; - toolbar_item_set_is_overflow (item, FALSE); + content->is_overflow = FALSE; } else { while (list) { - item = list->data; + content = list->data; + item = content->item; if (gtk_tool_item_get_pack_end (item)) - toolbar_item_set_is_overflow (item, TRUE); - + content->is_overflow = TRUE; + ++n_overflowed; list = list->prev; } break; @@ -1146,9 +1136,10 @@ gtk_toolbar_size_allocate (GtkWidget *widget, } /* calculate widths of pack front items */ - for (list = items, i = 0; list != NULL; list = list->next, ++i) + for (list = content, i = 0; list != NULL; list = list->next, ++i) { - GtkToolItem *item = list->data; + ToolbarContent *content = list->data; + GtkToolItem *item = content->item; gint item_size; if (gtk_tool_item_get_pack_end (item) || !toolbar_item_visible (toolbar, item)) @@ -1159,15 +1150,17 @@ gtk_toolbar_size_allocate (GtkWidget *widget, { size -= item_size; allocations[i].width = item_size; - toolbar_item_set_is_overflow (item, FALSE); + content->is_overflow = FALSE; } else { while (list) { - item = list->data; + content = list->data; + item = content->item; if (!gtk_tool_item_get_pack_end (item)) - toolbar_item_set_is_overflow (item, TRUE); + content->is_overflow = TRUE; + ++n_overflowed; list = list->next; } break; @@ -1181,47 +1174,61 @@ gtk_toolbar_size_allocate (GtkWidget *widget, } /* expand expandable items */ - n_expand_items = 0; - for (list = priv->items; list != NULL; list = list->next) + + /* We don't expand when dnd causes items to overflow. Doing so would result in + * weird jumps as items are overflowed and expandable items suddenly get lots of + * extra space. On the other hand we can't disable expanding completely, because + * that would cause a weird jump when dnd begins + */ + if (!(priv->in_dnd && n_overflowed > priv->n_overflow_items_when_dnd_started)) { - GtkToolItem *item = list->data; - - if (toolbar_item_visible (toolbar, item) && - gtk_tool_item_get_expand (item) && - !toolbar_item_get_is_overflow (item) && - !GTK_IS_SEPARATOR_TOOL_ITEM (item)) + n_expand_items = 0; + for (list = priv->content; list != NULL; list = list->next) { - n_expand_items++; + ToolbarContent *content = list->data; + GtkToolItem *item = content->item; + + if (toolbar_item_visible (toolbar, item) && + gtk_tool_item_get_expand (item) && + !content->is_overflow && + !GTK_IS_SEPARATOR_TOOL_ITEM (item)) + { + n_expand_items++; + } } - } - - for (list = items, i = 0; list != NULL; list = list->next, ++i) - { - GtkToolItem *item = list->data; - if (toolbar_item_visible (toolbar, item) && gtk_tool_item_get_expand (item) && - !toolbar_item_get_is_overflow (item) && - !GTK_IS_SEPARATOR_TOOL_ITEM (item)) + for (list = content, i = 0; list != NULL; list = list->next, ++i) { - gint extra = size / n_expand_items; - if (size % n_expand_items != 0) - extra++; - - allocations[i].width += extra; - size -= extra; - n_expand_items--; + ToolbarContent *content = list->data; + GtkToolItem *item = content->item; + + if (toolbar_item_visible (toolbar, item) && gtk_tool_item_get_expand (item) && + !content->is_overflow && + !GTK_IS_SEPARATOR_TOOL_ITEM (item)) + { + gint extra = size / n_expand_items; + if (size % n_expand_items != 0) + extra++; + + allocations[i].width += extra; + size -= extra; + n_expand_items--; + } } + + g_assert (n_expand_items == 0); } - - g_assert (n_expand_items == 0); /* position pack front items */ pos = border_width; - for (list = items, i = 0; list != NULL; list = list->next, ++i) + for (list = content, i = 0; list != NULL; list = list->next, ++i) { - GtkToolItem *item = list->data; + ToolbarContent *content = list->data; + GtkToolItem *item = content->item; - if (toolbar_item_visible (toolbar, item) && !toolbar_item_get_is_overflow (item) && !gtk_tool_item_get_pack_end (item)) + if (toolbar_item_visible (toolbar, item) && + !content->is_overflow && + !gtk_tool_item_get_pack_end (item)) { allocations[i].x = pos; allocations[i].y = border_width; @@ -1233,11 +1240,14 @@ gtk_toolbar_size_allocate (GtkWidget *widget, /* position pack end items */ pos = available_size + border_width; - for (list = g_list_last (items), i = 0; list != NULL; list = list->prev, ++i) + for (list = g_list_last (content), i = 0; list != NULL; list = list->prev, ++i) { - GtkToolItem *item = list->data; + ToolbarContent *content = list->data; + GtkToolItem *item = content->item; - if (toolbar_item_visible (toolbar, item) && !toolbar_item_get_is_overflow (item) && gtk_tool_item_get_pack_end (item)) + if (toolbar_item_visible (toolbar, item) && + !content->is_overflow && + gtk_tool_item_get_pack_end (item)) { GtkAllocation *allocation = &(allocations[n_items - i - 1]); @@ -1300,11 +1310,12 @@ gtk_toolbar_size_allocate (GtkWidget *widget, } /* finally allocate the items */ - for (list = items, i = 0; list != NULL; list = list->next, i++) + for (list = content, i = 0; list != NULL; list = list->next, i++) { - GtkToolItem *item = list->data; + ToolbarContent *content = list->data; + GtkToolItem *item = content->item; - if (toolbar_item_visible (toolbar, item) && !toolbar_item_get_is_overflow (item)) + if (toolbar_item_visible (toolbar, item) && !content->is_overflow) { gtk_widget_size_allocate (GTK_WIDGET (item), &(allocations[i])); gtk_widget_set_child_visible (GTK_WIDGET (item), TRUE); @@ -1327,7 +1338,7 @@ gtk_toolbar_size_allocate (GtkWidget *widget, } g_free (allocations); - g_list_free (items); + g_list_free (content); } static void @@ -1370,18 +1381,20 @@ gtk_toolbar_list_children_in_focus_order (GtkToolbar *toolbar, /* generate list of children in reverse logical order */ - for (list = priv->items; list != NULL; list = list->next) + for (list = priv->content; list != NULL; list = list->next) { - GtkToolItem *item = list->data; + ToolbarContent *content = list->data; + GtkToolItem *item = content->item; if (!gtk_tool_item_get_pack_end (item)) result = g_list_prepend (result, item); } result = g_list_prepend (result, priv->arrow_button); - for (list = priv->items; list != NULL; list = list->next) + for (list = priv->content; list != NULL; list = list->next) { - GtkToolItem *item = list->data; + ToolbarContent *content = list->data; + GtkToolItem *item = content->item; if (gtk_tool_item_get_pack_end (item)) result = g_list_prepend (result, item); @@ -1585,175 +1598,345 @@ gtk_toolbar_screen_changed (GtkWidget *widget, icon_size_change_notify (toolbar); } -static void -find_drop_pos (GtkToolbar *toolbar, - gint x, - gint y, - gint *drop_index, - gint *drop_pos) +static int +find_drop_index (GtkToolbar *toolbar, + gint x, + gint y) { GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar); + GList *interesting_content; + GList *list; GtkOrientation orientation; GtkTextDirection direction; - GList *items; - GtkToolItem *item; - gint border_width; - gint best_distance, best_pos, best_index, index; + gint best_distance = G_MAXINT; + gint distance; + gint cursor; + gint pos; + ToolbarContent *best_content; + + /* list items we care about wrt. drag and drop */ + interesting_content = NULL; + for (list = priv->content; list != NULL; list = list->next) + { + ToolbarContent *content = list->data; + GtkToolItem *item = content->item; + + if (!gtk_tool_item_get_pack_end (item) && + toolbar_item_visible (toolbar, item) && + !content->is_overflow) + { + interesting_content = g_list_prepend (interesting_content, content); + } + } + interesting_content = g_list_reverse (interesting_content); + + if (!interesting_content) + return 0; orientation = toolbar->orientation; direction = gtk_widget_get_direction (GTK_WIDGET (toolbar)); - border_width = GTK_CONTAINER (toolbar)->border_width + get_internal_padding (toolbar); - items = priv->items; - if (!items) + /* distance to first interesting item */ + best_content = interesting_content->data; + + if (orientation == GTK_ORIENTATION_HORIZONTAL) + { + cursor = x; + + if (direction == GTK_TEXT_DIR_LTR) + pos = GTK_WIDGET (best_content->item)->allocation.x; + else + pos = GTK_WIDGET (best_content->item)->allocation.x + + GTK_WIDGET (best_content->item)->allocation.width; + } + else + { + cursor = y; + pos = GTK_WIDGET (best_content->item)->allocation.y; + } + + best_content = NULL; + best_distance = ABS (pos - cursor); + + /* distance to far end of each item */ + for (list = interesting_content; list != NULL; list = list->next) { - *drop_index = 0; + ToolbarContent *content = list->data; + GtkWidget *widget = GTK_WIDGET (content->item); + if (orientation == GTK_ORIENTATION_HORIZONTAL) { - if (direction == GTK_TEXT_DIR_LTR) - *drop_pos = border_width; + if (direction == GTK_TEXT_DIR_LTR) + pos = widget->allocation.x + widget->allocation.width; else - *drop_pos = GTK_WIDGET (toolbar)->allocation.width - border_width; + pos = widget->allocation.x; } else { - *drop_pos = border_width; + pos = widget->allocation.y + widget->allocation.height; + } + + distance = ABS (pos - cursor); + + if (distance < best_distance) + { + best_distance = distance; + best_content = content; } - return; } - /* initial conditions */ - item = GTK_TOOL_ITEM (items->data); - best_index = 0; - if (orientation == GTK_ORIENTATION_HORIZONTAL) + g_list_free (interesting_content); + + if (!best_content) + return 0; + else + return g_list_index (priv->content, best_content) + 1; +} + +static void +get_size (GtkToolItem *tool_item, gint *width, gint *height) +{ + if (!GTK_WIDGET_VISIBLE (tool_item)) { - if (direction == GTK_TEXT_DIR_LTR) - best_pos = GTK_WIDGET (item)->allocation.x; - else - best_pos = GTK_WIDGET (item)->allocation.x + - GTK_WIDGET (item)->allocation.width; - best_distance = ABS (best_pos - x); + *width = 0; + *height = 0; } else { - best_pos = GTK_WIDGET (item)->allocation.y; - best_distance = ABS (best_pos - y); + GtkRequisition req; + + gtk_widget_get_child_requisition (GTK_WIDGET (tool_item), &req); + *width = req.width; + *height = req.height; } +} - index = 0; - while (items) +#define UPDATE_TIME (0.10) + +static gboolean +update_dnd_animation (gpointer data) +{ + GtkToolbar *toolbar = data; + GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar); + GList *list; + gboolean cont; + gdouble elapsed; + double error; + + GDK_THREADS_ENTER(); + + if (priv->need_sync) + gdk_flush (); + + elapsed = g_timer_elapsed (priv->timer, NULL); + + cont = FALSE; + + list = priv->content; + error = 0.0; + while (list) { - item = GTK_TOOL_ITEM (items->data); - index++; - if (GTK_WIDGET_DRAWABLE (item) && !gtk_tool_item_get_pack_end (item)) + ToolbarContent *content = list->data; + GtkWidget *widget = GTK_WIDGET (content->item); + GList *next = list->next; + gdouble exact_value; + gint start_value, goal_value; + gint new_value, prev_value; + + if (content->is_placeholder) { - gint pos, distance; + gint prev_width, prev_height; + + get_size (GTK_TOOL_ITEM (widget), &prev_width, &prev_height); + if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL) + { + start_value = content->start_width; + goal_value = content->goal_width; + prev_value = prev_width; + } + else + { + start_value = content->start_height; + goal_value = content->goal_height; + prev_value = prev_height; + } - if (orientation == GTK_ORIENTATION_HORIZONTAL) + if (elapsed <= UPDATE_TIME) { - if (direction == GTK_TEXT_DIR_LTR) - pos = GTK_WIDGET (item)->allocation.x + - GTK_WIDGET (item)->allocation.width; - else - pos = GTK_WIDGET (item)->allocation.x; - distance = ABS (pos - x); + exact_value = start_value + (elapsed / UPDATE_TIME) * (goal_value - start_value); + new_value = (int) (exact_value + error + 0.5); + + error += (exact_value - new_value); + + cont = TRUE; + } + else + { + exact_value = (double)goal_value; + new_value = goal_value; } + + if (new_value == 0) + gtk_widget_hide (widget); else + gtk_widget_show (widget); + + /* We need to check for "elapsed > UPDATE_TIME" so that the widget + * doesn't disappear before time. We need its contribution to + * the error value, even if its pixel width is 0. + */ + if (goal_value == 0 && elapsed > UPDATE_TIME) { - pos = GTK_WIDGET (item)->allocation.y + - GTK_WIDGET (item)->allocation.height; - distance = ABS (pos - y); + gtk_toolbar_remove_tool_item (toolbar, GTK_TOOL_ITEM (widget)); } - if (distance < best_distance) + else if (new_value != prev_value) { - best_index = index; - best_pos = pos; - best_distance = distance; + if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL) + gtk_widget_set_size_request (widget, new_value, 0); + else + gtk_widget_set_size_request (widget, 0, new_value); + + priv->need_sync = TRUE; + cont = TRUE; } } - items = items->next; + + list = next; + } + + gtk_widget_queue_resize_no_redraw (GTK_WIDGET (toolbar)); + + GDK_THREADS_LEAVE(); + + if (!cont) + { + priv->idle_id = 0; + if (priv->leaving_dnd) + { + priv->in_dnd = FALSE; + priv->leaving_dnd = FALSE; + priv->n_overflow_items_when_dnd_started = 0; + } + + return FALSE; } - *drop_index = best_index; - *drop_pos = best_pos; + + return TRUE; } static void -gtk_toolbar_drag_leave (GtkWidget *widget, - GdkDragContext *context, - guint time_) +ensure_idle_handler (GtkToolbar *toolbar) { - GtkToolbar *toolbar = GTK_TOOLBAR (widget); GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar); - if (priv->drag_highlight) + if (!priv->idle_id) + priv->idle_id = g_idle_add (update_dnd_animation, toolbar); +} + +static void +reset_all_placeholders (GtkToolbar *toolbar) +{ + GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar); + GList *list; + + for (list = priv->content; list != NULL; list = list->next) { - gdk_window_set_user_data (priv->drag_highlight, NULL); - gdk_window_destroy (priv->drag_highlight); - priv->drag_highlight = NULL; + ToolbarContent *content = list->data; + if (content->is_placeholder) + { + get_size (content->item, + &(content->start_width), &(content->start_height)); + content->goal_width = 0; + content->goal_height = 0; + } } - priv->drop_index = -1; + g_timer_reset (priv->timer); } -static gboolean -gtk_toolbar_drag_motion (GtkWidget *widget, - GdkDragContext *context, - gint x, - gint y, - guint time_) -{ - GtkToolbar *toolbar = GTK_TOOLBAR (widget); +void +gtk_toolbar_highlight_drop_location (GtkToolbar *toolbar, + gint x, + gint y, + gint width, + gint height) +{ + gint index; + ToolbarContent *content; GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar); - gint new_index, new_pos; + gint start_width, start_height; + GList *list; + + if (!priv->in_dnd) + { + priv->n_overflow_items_when_dnd_started = 0; + for (list = priv->content; list != NULL; list = list->next) + { + content = list->data; + if (content->is_overflow) + priv->n_overflow_items_when_dnd_started++; + } + } + + priv->in_dnd = TRUE; + priv->leaving_dnd = FALSE; + + index = find_drop_index (toolbar, x, y); - find_drop_pos(toolbar, x, y, &new_index, &new_pos); + content = g_list_nth_data (priv->content, index); - if (!priv->drag_highlight) + if (index > 0) { - GdkWindowAttr attributes; - guint attributes_mask; + ToolbarContent *prev_content; - attributes.window_type = GDK_WINDOW_CHILD; - attributes.wclass = GDK_INPUT_OUTPUT; - attributes.visual = gtk_widget_get_visual (widget); - attributes.colormap = gtk_widget_get_colormap (widget); - attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK | GDK_EXPOSURE_MASK | GDK_POINTER_MOTION_MASK; - attributes.width = 1; - attributes.height = 1; - attributes_mask = GDK_WA_VISUAL | GDK_WA_COLORMAP; - priv->drag_highlight = gdk_window_new (widget->window, - &attributes, attributes_mask); - gdk_window_set_user_data (priv->drag_highlight, widget); - gdk_window_set_background (priv->drag_highlight, - &widget->style->fg[widget->state]); - } + prev_content = g_list_nth_data (priv->content, index - 1); - if (priv->drop_index < 0 || - priv->drop_index != new_index) + if (prev_content && prev_content->is_placeholder) + content = prev_content; + } + + if (!content || !content->is_placeholder) { - gint border_width = GTK_CONTAINER (toolbar)->border_width; - priv->drop_index = new_index; - if (toolbar->orientation == GTK_ORIENTATION_HORIZONTAL) - { - gdk_window_move_resize (priv->drag_highlight, - widget->allocation.x + new_pos - 1, - widget->allocation.y + border_width, - 2, widget->allocation.height-border_width*2); - } - else - { - gdk_window_move_resize (priv->drag_highlight, - widget->allocation.x + border_width, - widget->allocation.y + new_pos - 1, - widget->allocation.width-border_width*2, 2); - } + GtkWidget *placeholder = GTK_WIDGET (gtk_separator_tool_item_new ()); + gtk_widget_set_size_request (placeholder, 0, 0); + gtk_toolbar_insert_tool_item (toolbar, GTK_TOOL_ITEM (placeholder), + index, TRUE); + content = g_list_nth_data (priv->content, index); + g_assert (content->is_placeholder); + start_width = start_height = 0; + } + else + { + get_size (content->item, &start_width, &start_height); } - gdk_window_show (priv->drag_highlight); + g_assert (content); + g_assert (content->is_placeholder); - gdk_drag_status (context, context->suggested_action, time_); + if (content->start_width != start_width || + content->start_height != start_height || + content->goal_width != width || + content->goal_height != height) + { + reset_all_placeholders (toolbar); + + content->start_width = start_width; + content->goal_width = width; + content->start_height = start_height; + content->goal_height = height; - return TRUE; + ensure_idle_handler (toolbar); + } +} + +void +gtk_toolbar_unhighlight_drop_location (GtkToolbar *toolbar) +{ + GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar); + + priv->leaving_dnd = TRUE; + reset_all_placeholders (toolbar); + ensure_idle_handler (toolbar); } static void @@ -1850,11 +2033,13 @@ gtk_toolbar_remove (GtkContainer *container, GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar); GList *list; - for (list = priv->items; list != NULL; list = list->next) + for (list = priv->content; list != NULL; list = list->next) { - if (GTK_BIN (list->data)->child == widget) + ToolbarContent *content = list->data; + + if (GTK_BIN (content->item)->child == widget) { - item = list->data; + item = content->item; break; } } @@ -1873,19 +2058,19 @@ gtk_toolbar_forall (GtkContainer *container, { GtkToolbar *toolbar = GTK_TOOLBAR (container); GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar); - GList *items; + GList *list; g_return_if_fail (callback != NULL); - items = priv->items; - - while (items) + list = priv->content; + while (list) { - GtkToolItem *item = GTK_TOOL_ITEM (items->data); + ToolbarContent *content = list->data; + GList *next = list->next; - items = items->next; + (*callback) (GTK_WIDGET (content->item), callback_data); - (*callback) (GTK_WIDGET (item), callback_data); + list = next; } if (include_internals) @@ -1902,16 +2087,17 @@ static void gtk_toolbar_reconfigured (GtkToolbar *toolbar) { GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar); - GList *items; + GList *list; - items = priv->items; - while (items) + list = priv->content; + while (list) { - GtkToolItem *item = GTK_TOOL_ITEM (items->data); + ToolbarContent *content = list->data; + GList *next = list->next; - _gtk_tool_item_toolbar_reconfigured (item); + _gtk_tool_item_toolbar_reconfigured (content->item); - items = items->next; + list = next; } } @@ -2021,11 +2207,12 @@ show_menu (GtkToolbar *toolbar, priv->menu = GTK_MENU (gtk_menu_new ()); g_signal_connect (priv->menu, "deactivate", G_CALLBACK (menu_deactivated), toolbar); - for (list = priv->items; list != NULL; list = list->next) + for (list = priv->content; list != NULL; list = list->next) { - GtkToolItem *item = list->data; + ToolbarContent *content = list->data; + GtkToolItem *item = content->item; - if (toolbar_item_visible (toolbar, item) && toolbar_item_get_is_overflow (item)) + if (toolbar_item_visible (toolbar, item) && content->is_overflow) { GtkWidget *menu_item = gtk_tool_item_retrieve_proxy_menu_item (item); @@ -2182,16 +2369,72 @@ gtk_toolbar_check_new_api (GtkToolbar *toolbar) return TRUE; } +static gint +physical_to_logical (GtkToolbar *toolbar, gint physical) +{ + GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar); + GList *list; + int logical; + + if (physical < 0) + return -1; + + logical = 0; + for (list = priv->content; list; list = list->next) + { + ToolbarContent *content = list->data; + + if (!physical) + return logical; + + if (!content->is_placeholder) + logical++; + physical--; + } + return -1; +} + +static gint +logical_to_physical (GtkToolbar *toolbar, gint logical) +{ + GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar); + GList *list; + gint physical; + + if (logical < 0) + return -1; + + physical = 0; + for (list = priv->content; list; list = list->next) + { + ToolbarContent *content = list->data; + + if (!logical) + return physical; + + if (!content->is_placeholder) + logical--; + physical++; + } + return -1; +} + static void gtk_toolbar_insert_tool_item (GtkToolbar *toolbar, GtkToolItem *item, - gint pos) + gint pos, + gboolean is_placeholder) { GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar); - - priv->items = g_list_insert (priv->items, item, pos); + ToolbarContent *content = g_new0 (ToolbarContent, 1); + + content->is_overflow = FALSE; + content->is_placeholder = is_placeholder; + content->item = item; toolbar->num_children++; + priv->content = g_list_insert (priv->content, content, pos); + gtk_widget_set_parent (GTK_WIDGET (item), GTK_WIDGET (toolbar)); } @@ -2202,23 +2445,29 @@ gtk_toolbar_remove_tool_item (GtkToolbar *toolbar, GtkToolbarPrivate *priv; GList *tmp; gint nth_child; + ToolbarContent *content = NULL; g_return_if_fail (GTK_IS_TOOLBAR (toolbar)); - priv = GTK_TOOLBAR_GET_PRIVATE (toolbar); g_return_if_fail (GTK_IS_TOOL_ITEM (item)); - g_return_if_fail (g_list_find (priv->items, item)); + + priv = GTK_TOOLBAR_GET_PRIVATE (toolbar); nth_child = 0; - for (tmp = priv->items; tmp != NULL; tmp = tmp->next) + for (tmp = priv->content; tmp != NULL; tmp = tmp->next) { - if (tmp->data == item) + content = tmp->data; + if (content->item == item) break; nth_child++; } - priv->items = g_list_remove (priv->items, item); + g_return_if_fail (content != NULL); + + g_free (content); + + priv->content = g_list_remove (priv->content, content); gtk_widget_unparent (GTK_WIDGET (item)); @@ -2260,7 +2509,7 @@ gtk_toolbar_new (void) * * Insert a #GtkToolItem into the toolbar at position @pos. If @pos is * 0 the item is prepended to the start of the toolbar. If @pos is - * negative, append the item to the end of the toolbar. + * negative, the item is appended to the end of the toolbar. * * Since: 2.4 **/ @@ -2274,8 +2523,9 @@ gtk_toolbar_insert (GtkToolbar *toolbar, if (!gtk_toolbar_check_new_api (toolbar)) return; - - gtk_toolbar_insert_tool_item (toolbar, item, pos); + + gtk_toolbar_insert_tool_item (toolbar, item, + logical_to_physical (toolbar, pos), FALSE); } /** @@ -2295,17 +2545,30 @@ gtk_toolbar_get_item_index (GtkToolbar *toolbar, GtkToolItem *item) { GtkToolbarPrivate *priv; + GList *list; + int n; g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), -1); g_return_val_if_fail (GTK_IS_TOOL_ITEM (item), -1); + g_return_val_if_fail (GTK_WIDGET (item)->parent == GTK_WIDGET (toolbar), -1); if (!gtk_toolbar_check_new_api (toolbar)) return -1; priv = GTK_TOOLBAR_GET_PRIVATE (toolbar); - g_return_val_if_fail (g_list_find (priv->items, item) != NULL, -1); - return g_list_index (priv->items, item); + n = 0; + for (list = priv->content; list != NULL; list = list->next) + { + ToolbarContent *content = list->data; + + if (content->item == item) + break; + + ++n; + } + + return physical_to_logical (toolbar, n); } /** @@ -2466,8 +2729,11 @@ gtk_toolbar_get_n_items (GtkToolbar *toolbar) return -1; priv = GTK_TOOLBAR_GET_PRIVATE (toolbar); - - return g_list_length (priv->items); + + if (!priv->content) + return 0; + + return physical_to_logical (toolbar, g_list_length (priv->content) - 1); } /** @@ -2488,15 +2754,21 @@ gtk_toolbar_get_nth_item (GtkToolbar *toolbar, gint n) { GtkToolbarPrivate *priv; - + ToolbarContent *content; + g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), NULL); if (!gtk_toolbar_check_new_api (toolbar)) return NULL; priv = GTK_TOOLBAR_GET_PRIVATE (toolbar); + + content = g_list_nth_data (priv->content, logical_to_physical (toolbar, n)); - return g_list_nth_data (priv->items, n); + if (content) + return content->item; + + return NULL; } /** @@ -2679,16 +2951,12 @@ gtk_toolbar_get_drop_index (GtkToolbar *toolbar, gint x, gint y) { - gint drop_index, drop_pos; - g_return_val_if_fail (GTK_IS_TOOLBAR (toolbar), FALSE); - + if (!gtk_toolbar_check_new_api (toolbar)) return -1; - find_drop_pos (toolbar, x, y, &drop_index, &drop_pos); - - return drop_index; + return physical_to_logical (toolbar, find_drop_index (toolbar, x, y)); } /** @@ -3248,7 +3516,7 @@ gtk_toolbar_internal_insert_element (GtkToolbar *toolbar, toolbar->children = g_list_insert (toolbar->children, child, position); - gtk_toolbar_insert_tool_item (toolbar, item, position); + gtk_toolbar_insert_tool_item (toolbar, item, position, FALSE); return child->widget; } @@ -3258,7 +3526,8 @@ gtk_toolbar_finalize (GObject *object) { GList *list; GtkToolbar *toolbar = GTK_TOOLBAR (object); - + GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar); + if (toolbar->tooltips) g_object_unref (toolbar->tooltips); @@ -3266,6 +3535,16 @@ gtk_toolbar_finalize (GObject *object) g_free (list->data); g_list_free (toolbar->children); + + for (list = priv->content; list != NULL; list = list->next) + g_free (list->data); + + g_list_free (priv->content); + + g_timer_destroy (priv->timer); + + if (priv->idle_id) + g_source_remove (priv->idle_id); G_OBJECT_CLASS (parent_class)->finalize (object); } diff --git a/gtk/gtktoolbar.h b/gtk/gtktoolbar.h index f4e64d31de..0e0f50d557 100644 --- a/gtk/gtktoolbar.h +++ b/gtk/gtktoolbar.h @@ -91,21 +91,21 @@ typedef struct _GtkToolbarPrivate GtkToolbarPrivate; struct _GtkToolbar { GtkContainer container; - + gint num_children; GList *children; GtkOrientation orientation; GtkToolbarStyle style; GtkIconSize icon_size; - + GtkTooltips *tooltips; gint button_maxw; /* maximum width of homogeneous children */ gint button_maxh; /* maximum height of homogeneous children */ - + guint style_set_connection; guint icon_size_connection; - + guint style_set : 1; guint icon_size_set : 1; }; @@ -113,7 +113,7 @@ struct _GtkToolbar struct _GtkToolbarClass { GtkContainerClass parent_class; - + /* signals */ void (* orientation_changed) (GtkToolbar *toolbar, GtkOrientation orientation); @@ -123,7 +123,7 @@ struct _GtkToolbarClass gint x, gint y, gint button_number); - + /* Padding for future expansion */ void (*_gtk_reserved1) (void); void (*_gtk_reserved2) (void); @@ -131,33 +131,39 @@ struct _GtkToolbarClass }; GType gtk_toolbar_get_type (void) G_GNUC_CONST; -GtkWidget* gtk_toolbar_new (void); -void gtk_toolbar_insert (GtkToolbar *toolbar, - GtkToolItem *item, - gint pos); -gint gtk_toolbar_get_item_index (GtkToolbar *toolbar, - GtkToolItem *item); -gint gtk_toolbar_get_n_items (GtkToolbar *toolbar); -GtkToolItem * gtk_toolbar_get_nth_item (GtkToolbar *toolbar, - gint n); -gint gtk_toolbar_get_drop_index (GtkToolbar *toolbar, - gint x, - gint y); -void gtk_toolbar_set_show_arrow (GtkToolbar *toolbar, - gboolean show_arrow); -void gtk_toolbar_set_orientation (GtkToolbar *toolbar, - GtkOrientation orientation); -void gtk_toolbar_set_tooltips (GtkToolbar *toolbar, - gboolean enable); -gboolean gtk_toolbar_get_show_arrow (GtkToolbar *toolbar); -GtkOrientation gtk_toolbar_get_orientation (GtkToolbar *toolbar); -GtkToolbarStyle gtk_toolbar_get_style (GtkToolbar *toolbar); -GtkIconSize gtk_toolbar_get_icon_size (GtkToolbar *toolbar); -gboolean gtk_toolbar_get_tooltips (GtkToolbar *toolbar); -GtkReliefStyle gtk_toolbar_get_relief_style (GtkToolbar *toolbar); -void gtk_toolbar_set_style (GtkToolbar *toolbar, - GtkToolbarStyle style); -void gtk_toolbar_unset_style (GtkToolbar *toolbar); +GtkWidget* gtk_toolbar_new (void); +void gtk_toolbar_insert (GtkToolbar *toolbar, + GtkToolItem *item, + gint pos); +gint gtk_toolbar_get_item_index (GtkToolbar *toolbar, + GtkToolItem *item); +gint gtk_toolbar_get_n_items (GtkToolbar *toolbar); +GtkToolItem * gtk_toolbar_get_nth_item (GtkToolbar *toolbar, + gint n); +void gtk_toolbar_set_show_arrow (GtkToolbar *toolbar, + gboolean show_arrow); +void gtk_toolbar_set_orientation (GtkToolbar *toolbar, + GtkOrientation orientation); +void gtk_toolbar_set_tooltips (GtkToolbar *toolbar, + gboolean enable); +gboolean gtk_toolbar_get_show_arrow (GtkToolbar *toolbar); +GtkOrientation gtk_toolbar_get_orientation (GtkToolbar *toolbar); +GtkToolbarStyle gtk_toolbar_get_style (GtkToolbar *toolbar); +GtkIconSize gtk_toolbar_get_icon_size (GtkToolbar *toolbar); +gboolean gtk_toolbar_get_tooltips (GtkToolbar *toolbar); +GtkReliefStyle gtk_toolbar_get_relief_style (GtkToolbar *toolbar); +void gtk_toolbar_set_style (GtkToolbar *toolbar, + GtkToolbarStyle style); +void gtk_toolbar_unset_style (GtkToolbar *toolbar); +gint gtk_toolbar_get_drop_index (GtkToolbar *toolbar, + gint x, + gint y); +void gtk_toolbar_highlight_drop_location (GtkToolbar *toolbar, + gint x, + gint y, + gint width, + gint height); +void gtk_toolbar_unhighlight_drop_location (GtkToolbar *toolbar); diff --git a/tests/testtoolbar.c b/tests/testtoolbar.c index 4eab1e3bf4..2127676b66 100644 --- a/tests/testtoolbar.c +++ b/tests/testtoolbar.c @@ -472,6 +472,28 @@ popup_context_menu (GtkToolbar *toolbar, gint x, gint y, gint button_number) return TRUE; } +static gboolean +toolbar_drag_motion (GtkToolbar *toolbar, + GdkDragContext *context, + gint x, + gint y, + guint time, + gpointer null) +{ + gdk_drag_status (context, GDK_ACTION_MOVE, time); + gtk_toolbar_highlight_drop_location (toolbar, x, y, 100, 60); + return TRUE; +} + +static void +toolbar_drag_leave (GtkToolbar *toolbar, + GdkDragContext *context, + guint time, + gpointer null) +{ + gtk_toolbar_unhighlight_drop_location (toolbar); +} + gint main (gint argc, gchar **argv) { @@ -577,6 +599,7 @@ main (gint argc, gchar **argv) gtk_tool_button_set_label (GTK_TOOL_BUTTON (item), NULL); add_item_to_list (store, item, "New"); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1); + gtk_tool_item_set_expand (item, TRUE); item = gtk_tool_button_new_from_stock (GTK_STOCK_OPEN); add_item_to_list (store, item, "Open"); @@ -624,7 +647,10 @@ main (gint argc, gchar **argv) add_item_to_list (store, item, "Left"); gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1); - item = gtk_radio_tool_button_new_from_stock (group, GTK_STOCK_JUSTIFY_CENTER); make_prop_editor (G_OBJECT (item)); + item = gtk_radio_tool_button_new_from_stock (group, GTK_STOCK_JUSTIFY_CENTER); +#if 0 + make_prop_editor (G_OBJECT (item)); +#endif group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (item)); add_item_to_list (store, item, "Center"); @@ -668,12 +694,18 @@ main (gint argc, gchar **argv) gtk_drag_dest_set (toolbar, GTK_DEST_DEFAULT_DROP, target_table, G_N_ELEMENTS (target_table), GDK_ACTION_MOVE); + g_signal_connect (toolbar, "drag_motion", + G_CALLBACK (toolbar_drag_motion), NULL); + g_signal_connect (toolbar, "drag_leave", + G_CALLBACK (toolbar_drag_leave), NULL); g_signal_connect (toolbar, "drag_drop", G_CALLBACK (toolbar_drag_drop), label); gtk_widget_show_all (window); +#if 0 make_prop_editor (G_OBJECT (toolbar)); +#endif g_signal_connect (window, "delete_event", G_CALLBACK (gtk_main_quit), NULL); -- 2.30.2